# add_module.cmake

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOGEN ON)
set(SOURCES "")
set(HEADERS "")
set(REPFILE "")
set(UIFILES "")
add_definitions(-DOPENHARMONY_TEST)
add_definitions(-DQ_OS_OPENHARMONY)
cmake_policy(SET CMP0071 NEW)


list(APPEND CMAKE_FIND_ROOT_PATH ${QT_PREFIX})
#####################################################################
# 获取当前.cmake文件的路径和根目录,
# 并打印了模块路径，用于调试和确认路径正确性
#####################################################################
set(CURRENT_DIR "${CMAKE_CURRENT_LIST_DIR}")
get_filename_component(ROOT_DIR "${CURRENT_DIR}" DIRECTORY)
#message("Module path: ${ROOT_DIR}")
#END

#####################################################################
# 定义查找所有项
#####################################################################
function(find_all RETURN_VAR)
    # 获取当前目录下的所有项
    set(SUBDIR_PATH "${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}")

    file(GLOB ALL_ITEMS RELATIVE "${SUBDIR_PATH}" "${SUBDIR_PATH}/*")

    # 初始化一个空列表用于存储子目录
    set(SUBDIRS_LIST)

    # 过滤出目录
    foreach(ITEM IN LISTS ALL_ITEMS)
        if(IS_DIRECTORY "${SUBDIR_PATH}/${ITEM}")
            list(APPEND SUBDIRS_LIST "${ITEM}")
        endif()
    endforeach()

    # 将找到的子目录列表通过外部变量“返回”
    set(${RETURN_VAR} ${SUBDIRS_LIST} PARENT_SCOPE)
endfunction()
#####################################################################

#####################################################################
# 指定目录下递归查找所有项和子目录
#####################################################################
function(find_subdirs DIR RETURN_VAR)
    # 获取当前目录下的所有项
    file(GLOB ALL_ITEMS RELATIVE "${DIR}" "${DIR}/*")

    # 初始化一个空列表用于存储子目录
    set(SUBDIRS_LIST)

    # 过滤出目录并递归调用
    foreach(ITEM IN LISTS ALL_ITEMS)
        if(IS_DIRECTORY "${DIR}/${ITEM}")
            # 将当前找到的子目录添加到列表
            list(APPEND SUBDIRS_LIST "${ITEM}")
            # 递归调用以找到更深层次的子目录
            find_subdirs("${DIR}/${ITEM}" SUBDIRS_RECURSIVE)
            # 将递归找到的子目录追加到列表
            foreach(SUBDIR IN LISTS SUBDIRS_RECURSIVE)
                list(APPEND SUBDIRS_LIST "${ITEM}/${SUBDIR}")
            endforeach()
        endif()
    endforeach()

    # 将找到的子目录列表通过外部变量“返回”
    set(${RETURN_VAR} "${SUBDIRS_LIST}" PARENT_SCOPE)
endfunction()
#####################################################################


macro(qt5_generate_repc_rep outfiles infile)
    # get include dirs and flags
    get_filename_component(abs_infile ${infile} ABSOLUTE)
    get_filename_component(infile_name "${infile}" NAME)
    string(REPLACE ".h" "" _infile_base ${infile_name})

    set(_outfile_base "rep_${_infile_base}_replica")
    set(_repc_args -o replica)

    set(_outfile_header "${CMAKE_CURRENT_BINARY_DIR}/${_outfile_base}.h")
    add_custom_command(OUTPUT ${_outfile_header}
        DEPENDS ${abs_infile}
        COMMAND ${Qt5RemoteObjects_REPC_EXECUTABLE} ${abs_infile} ${_repc_args} ${_outfile_header}
        VERBATIM)
    set_source_files_properties(${_outfile_header} PROPERTIES GENERATED TRUE)

    qt5_get_moc_flags(_moc_flags)
    # Make sure we get the compiler flags from the Qt5::RemoteObjects target (for includes)
    # (code adapted from QT5_GET_MOC_FLAGS)
    foreach(_current ${Qt5RemoteObjects_INCLUDE_DIRS})
        if("${_current}" MATCHES "\\.framework/?$")
            string(REGEX REPLACE "/[^/]+\\.framework" "" framework_path "${_current}")
            set(_moc_flags ${_moc_flags} "-F${framework_path}")
        else()
            set(_moc_flags ${_moc_flags} "-I${_current}")
        endif()
    endforeach()

    set(_moc_outfile "${CMAKE_CURRENT_BINARY_DIR}/moc_${_outfile_base}.cpp")
    qt5_create_moc_command(${_outfile_header} ${_moc_outfile} "${_moc_flags}" "" "" "")
    list(APPEND ${outfiles} "${_outfile_header}" ${_moc_outfile})
endmacro()

macro(qt5_generate_repc_merged outfiles infile)
    # get include dirs and flags
    get_filename_component(abs_infile ${infile} ABSOLUTE)
    get_filename_component(infile_name "${infile}" NAME)
    string(REPLACE ".rep" "" _infile_base ${infile_name})

    set(_outfile_base "rep_${_infile_base}_merged")
    set(_repc_args -o merged)

    set(_outfile_header "${CMAKE_CURRENT_BINARY_DIR}/${_outfile_base}.h")
    add_custom_command(OUTPUT ${_outfile_header}
        DEPENDS ${abs_infile}
        COMMAND ${Qt5RemoteObjects_REPC_EXECUTABLE} ${abs_infile} ${_repc_args} ${_outfile_header}
        VERBATIM)
    set_source_files_properties(${_outfile_header} PROPERTIES GENERATED TRUE)

    qt5_get_moc_flags(_moc_flags)
    # Make sure we get the compiler flags from the Qt5::RemoteObjects target (for includes)
    # (code adapted from QT5_GET_MOC_FLAGS)
    foreach(_current ${Qt5RemoteObjects_INCLUDE_DIRS})
        if("${_current}" MATCHES "\\.framework/?$")
            string(REGEX REPLACE "/[^/]+\\.framework" "" framework_path "${_current}")
            set(_moc_flags ${_moc_flags} "-F${framework_path}")
        else()
            set(_moc_flags ${_moc_flags} "-I${_current}")
        endif()
    endforeach()

    set(_moc_outfile "${CMAKE_CURRENT_BINARY_DIR}/moc_${_outfile_base}.cpp")
    qt5_create_moc_command(${_outfile_header} ${_moc_outfile} "${_moc_flags}" "" "" "")
    list(APPEND ${outfiles} "${_outfile_header}" ${_moc_outfile})
endmacro()


#####################################################################
# 生成测试库宏
#####################################################################
macro(create_library TEST_ITEMS)
    foreach(QT_LIB IN LISTS LinkQt)
        find_package(QT NAMES Qt5 REQUIRED COMPONENTS ${QT_LIB})
        find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS ${QT_LIB})
        set(QT_MODULE_INCLUDE_DIRS ${Qt${QT_VERSION_MAJOR}${QT_LIB}_INCLUDE_DIRS})
        foreach(i ${QT_MODULE_INCLUDE_DIRS})
            list(APPEND MOC_INCLUDE_DIRS -I${i})
        endforeach()
    endforeach()
#    message(MOC_INCLUDE_DIRS=${MOC_INCLUDE_DIRS})
    #排除不需要的测试
    foreach(item IN LISTS EXCLUDE)
        list(REMOVE_ITEM TEST_ITEMS ${item})
    endforeach()

    # 添加子目录下的源文件、头文件、资源文件、ui文件
    foreach(item IN LISTS TEST_ITEMS)
        set(SUBDIR_PATH "${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${item}")
        file(GLOB_RECURSE TEMP_SOURCES "${SUBDIR_PATH}/*.cpp")
        file(GLOB_RECURSE TEMP_HEADERS "${SUBDIR_PATH}/*.h")
        file(GLOB_RECURSE TEMP_QRCFILE "${SUBDIR_PATH}/*.qrc")
        file(GLOB_RECURSE TEMP_UIFILES "${SUBDIR_PATH}/*.ui")
		# 过滤掉所有路径名中包含"main.cpp"或"main_win.cpp"的文件
		list(FILTER TEMP_SOURCES EXCLUDE REGEX "main(_win)?\\.cpp$")
		# 过滤掉"mainXXX.cpp"文件
		list(FILTER TEMP_SOURCES EXCLUDE REGEX "main([0-9][0-9][0-9])\\.cpp$")
        list(APPEND SOURCES ${TEMP_SOURCES})
        list(APPEND HEADERS ${TEMP_HEADERS})
        list(APPEND QRCFILE ${TEMP_QRCFILE})
        list(APPEND UIFILES ${TEMP_UIFILES})
    endforeach()

    # 查找shared下面的qrc文件
    file(GLOB_RECURSE SHARED_QRCFILE "${ROOT_DIR}/${MODULE}/tests/shared/*.qrc")
    list(APPEND QRCFILE ${SHARED_QRCFILE})

    foreach(item IN LISTS REP_REPLICA)
        message(REP_REPLICA=${REP_REPLICA})
        qt5_generate_repc(OUT_REP_REPLICA ${item} REPLICA)
        list(APPEND REPFILE ${OUT_REP_REPLICA})
    endforeach()

    foreach(item IN LISTS REP_SOURCES)
        message(REP_SOURCES=${REP_SOURCES})
        qt5_generate_repc(OUT_REP_SOURCES ${item} SOURCE)
        list(APPEND REPFILE ${OUT_REP_SOURCES})
    endforeach()



    foreach(item IN LISTS REP_MERGEDS)
        message(REP_MERGEDS=${REP_MERGEDS})
        qt5_generate_repc_merged(OUT_REP_SOURCES ${item} SOURCE)
        list(APPEND REPFILE ${OUT_REP_SOURCES})
    endforeach()

    foreach(item IN LISTS REP_FILES)
        message(REP_FILES=${REP_FILES})
        qt5_generate_repc_rep(OUT_REP_SOURCES ${item} SOURCE)
        list(APPEND REPFILE ${OUT_REP_SOURCES})
    endforeach()

	#没定义MANUAL_ADD_MAIN时，根据引用的库添加main文件
	if(NOT DEFINED MANUAL_ADD_MAIN)
		# 检查是否包含Qt Widgets和Qt Gui模块
		list(FIND LinkQt Widgets ITEM_INDEX_WIDGETS)
		list(FIND LinkQt Gui ITEM_INDEX_GUI)
		# 根据找到的模块决定添加哪个主函数
		if(ITEM_INDEX_WIDGETS GREATER -1) # 如果找到了Widgets模块
		    message("include widget_main.cpp")
			list(APPEND SOURCES ${ROOT_DIR}/cmake/maincpp/widget_main.cpp)
		elseif(ITEM_INDEX_GUI GREATER -1) # 如果找到了Gui模块，但Widgets没有找到
			list(APPEND SOURCES ${ROOT_DIR}/cmake/maincpp/gui_main.cpp)
		else() # 如果Widgets和Gui都没有找到
			list(APPEND SOURCES ${ROOT_DIR}/cmake/maincpp/core_main.cpp)
		endif()
	else()
		if(MANUAL_ADD_MAIN EQUAL 0)
			list(APPEND SOURCES ${ROOT_DIR}/cmake/maincpp/widget_main.cpp)
		elseif(MANUAL_ADD_MAIN EQUAL 1)
			list(APPEND SOURCES ${ROOT_DIR}/cmake/maincpp/gui_main.cpp)
		elseif(MANUAL_ADD_MAIN EQUAL 2)
			list(APPEND SOURCES ${ROOT_DIR}/cmake/maincpp/core_main.cpp)
        elseif(MANUAL_ADD_MAIN EQUAL 3)
            list(APPEND SOURCES ${ROOT_DIR}/cmake/maincpp/appless_main.cpp)
        elseif(MANUAL_ADD_MAIN EQUAL 4)
            list(APPEND SOURCES ${ROOT_DIR}/cmake/maincpp/none_main.cpp)
		else()
		    list(APPEND SOURCES ${ROOT_DIR}/cmake/maincpp/none_main.cpp)
		endif()
	endif()



    # 整合文件
    set(PROJECT_SOURCES ${SOURCES} ${HEADERS} ${QRCFILE} ${UIFILES} ${REPFILE})
    # 排除不需要的文件
    foreach(item IN LISTS EXCLUDE_SRC)
        list(REMOVE_ITEM PROJECT_SOURCES ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${item})
    endforeach()
    #moc手动处理MOC的源文件
    foreach(item IN LISTS MANUAL_MOC_SOURCES)
        list(REMOVE_ITEM PROJECT_SOURCES ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${item})
    endforeach()

    #手动创建moc_xxxx.cpp文件
    foreach(item IN LISTS MANUAL_MOC_HEADERS)
        qt5_wrap_cpp(PROJECT_SOURCES ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${item} OPTIONS ${MOC_INCLUDE_DIRS})
    endforeach()


    # 创建库
    add_library(${PROJECT_NAME} SHARED  ${PROJECT_SOURCES})

    # add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})

    target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})

    # 添加头文件路径
    foreach(header IN LISTS HEADERS)
        get_filename_component(HEADER_PATH ${header} DIRECTORY)
#        message(=========HEADER_PATH=${HEADER_PATH})
        target_include_directories(${PROJECT_NAME} PUBLIC ${HEADER_PATH})
    endforeach()
    # 添加总头文件路径
    target_include_directories(${PROJECT_NAME} PUBLIC ${ROOT_DIR}/harmony)
    # 添加QtTest库
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Test)
    target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Test)
 	# 添加QtQuickTest库
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Quick QuickTest)
    target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Quick Qt${QT_VERSION_MAJOR}::QuickTest)
 	
	##totaltest.h中需要Gui和Widget库（放到main函数选择后面）
	# 添加Gui库
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui)
    target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Gui)
	# 添加Widget库
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
    target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
	
    # 添加Qt库
    foreach(QT_LIB IN LISTS LinkQt)
        target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::${QT_LIB})
    endforeach()

    # 添加Qt Private库
    foreach(QT_LIB IN LISTS LinkQtPrivate)
        target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::${QT_LIB}Private)
    endforeach()

    # 添加Qt 插件
    foreach(QT_PLUGIN IN LISTS PLUGINS)
        target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::${QT_PLUGIN})
    endforeach()

    message(CURRENTTESTITEM: ${PROJECT_NAME})
endmacro()

#####################################################################
 # 生成测试库宏(create_exe)
 #####################################################################
 macro(create_exe TEST_ITEMS)

     foreach(QT_LIB IN LISTS LinkQt)
         find_package(QT NAMES Qt5 REQUIRED COMPONENTS ${QT_LIB})
         find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS ${QT_LIB})
     endforeach()

     #排除不需要的测试
     foreach(item IN LISTS EXCLUDE)
         list(REMOVE_ITEM TEST_ITEMS ${item})
     endforeach()

     # 添加子目录下的源文件、头文件、资源文件、ui文件
     foreach(item IN LISTS TEST_ITEMS)
         set(SUBDIR_PATH "${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${item}")
         file(GLOB_RECURSE TEMP_SOURCES "${SUBDIR_PATH}/*.cpp")
         file(GLOB_RECURSE TEMP_HEADERS "${SUBDIR_PATH}/*.h")
         file(GLOB_RECURSE TEMP_QRCFILE "${SUBDIR_PATH}/*.qrc")
         file(GLOB_RECURSE TEMP_UIFILES "${SUBDIR_PATH}/*.ui")
         # 过滤掉所有路径名中包含"main.cpp"或"main_win.cpp"的文件
         # list(FILTER TEMP_SOURCES EXCLUDE REGEX "main(_win)?\\.cpp$")
         list(APPEND SOURCES ${TEMP_SOURCES})
         list(APPEND HEADERS ${TEMP_HEADERS})
         list(APPEND QRCFILE ${TEMP_QRCFILE})
         list(APPEND UIFILES ${TEMP_UIFILES})
     endforeach()

     foreach(item IN LISTS REP_REPLICA)
         message(REP_REPLICA=${REP_REPLICA})
         qt5_generate_repc(OUT_REP_REPLICA ${item} REPLICA)
         list(APPEND REPFILE ${OUT_REP_REPLICA})
     endforeach()

     foreach(item IN LISTS REP_SOURCES)
         message(REP_SOURCES=${REP_SOURCES})
         qt5_generate_repc(OUT_REP_SOURCES ${item} SOURCE)
         list(APPEND REPFILE ${OUT_REP_SOURCES})
     endforeach()



     foreach(item IN LISTS REP_MERGEDS)
         message(REP_MERGEDS=${REP_MERGEDS})
         qt5_generate_repc_merged(OUT_REP_SOURCES ${item} SOURCE)
         list(APPEND REPFILE ${OUT_REP_SOURCES})
     endforeach()

     foreach(item IN LISTS REP_FILES)
         message(REP_FILES=${REP_FILES})
         qt5_generate_repc_rep(OUT_REP_SOURCES ${item} SOURCE)
         list(APPEND REPFILE ${OUT_REP_SOURCES})
     endforeach()

     # 添加主函数
     # list(APPEND SOURCES ${ROOT_DIR}/cmake/maincpp/core_main.cpp)
     # 判断是否需要添加GUI主函数
     # list(FIND LinkQt Widgets ITEM_INDEX_WIDGETS)
     # list(FIND LinkQt Gui ITEM_INDEX_GUI)
     # if(NOT ITEM_INDEX_WIDGETS EQUAL -1 OR NOT ITEM_INDEX_GUI EQUAL -1)
     #     if(NOT GUI_MAIN_ADDED) # 如果GUI主函数还未添加
     #         list(REMOVE_ITEM SOURCES ${ROOT_DIR}/cmake/maincpp/core_main.cpp)
     #         list(APPEND SOURCES ${ROOT_DIR}/cmake/maincpp/gui_main.cpp)
     #     endif()
     # endif()

     # 整合文件
     set(PROJECT_SOURCES ${SOURCES} ${HEADERS} ${QRCFILE} ${UIFILES} ${REPFILE})
     # 排除不需要的文件
     foreach(item IN LISTS EXCLUDE_SRC)
         list(REMOVE_ITEM PROJECT_SOURCES ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${item})
     endforeach()
     # 创建库
     # add_library(${PROJECT_NAME} SHARED  ${PROJECT_SOURCES})
     add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})

     target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
     target_include_directories(${PROJECT_NAME} PUBLIC ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE})

     # 添加头文件路径
     foreach(header IN LISTS HEADERS)
         get_filename_component(HEADER_PATH ${header} DIRECTORY)
         target_include_directories(${PROJECT_NAME} PUBLIC ${HEADER_PATH})
     endforeach()
     # 添加总头文件路径
     target_include_directories(${PROJECT_NAME} PUBLIC ${ROOT_DIR}/harmony)
     # 添加QtTest库
     find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Test)
     target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Test)
     # 添加Qt库
     foreach(QT_LIB IN LISTS LinkQt)
         target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::${QT_LIB})
     endforeach()

     # 添加Qt Private库
     foreach(QT_LIB IN LISTS LinkQtPrivate)
         target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::${QT_LIB}Private)
     endforeach()

     # 设置库文件的输出目录
     # set_target_properties(${PROJECT_NAME} PROPERTIES
     #   LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../../../libs/arm64-v8a"
     #   ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../../../libs/arm64-v8a" # 对于静态库
     #   # RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../../../bin" # 对于 Windows 上的 DLL 运行时
     # )

     message(CURRENT TESTITEM: ${PROJECT_NAME})
 endmacro()

function(add_sources)
    message("========${ARGC}========")
    foreach(arg IN LISTS ARGV)
        list(APPEND SOURCES ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${arg})
        message("${arg}")
    endforeach()
    # 更新SOURCES变量到父作用域，如果这个宏在一个函数内被调用
    set(SOURCES ${SOURCES} PARENT_SCOPE)
endfunction()

function(add_headers)
    foreach(arg IN LISTS ARGN)
        list(APPEND HEADERS ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${arg})
        # message("${arg}")
    endforeach()
    # 更新SOURCES变量到父作用域，如果这个宏在一个函数内被调用
    set(HEADERS ${HEADERS} PARENT_SCOPE)
endfunction()

function(add_sources)
#    message("========${ARGC}========")
    foreach(arg IN LISTS ARGV)
        list(APPEND SOURCES ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${arg})
#        message("${arg}")
    endforeach()
    # 更新SOURCES变量到父作用域，如果这个宏在一个函数内被调用
    set(SOURCES ${SOURCES} PARENT_SCOPE)
endfunction()

function(add_headers)
    foreach(arg IN LISTS ARGN)
        list(APPEND HEADERS ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${arg})
        # message("${arg}")
    endforeach()
    # 更新SOURCES变量到父作用域，如果这个宏在一个函数内被调用
    set(HEADERS ${HEADERS} PARENT_SCOPE)
endfunction()

macro(qt_generate_rep_replica REP_FILE)
    message(-------${REP_FILE}-------)
  # 确定输出文件名
  get_filename_component(FILE_NAME ${REP_FILE} NAME_WE)
  # set(OUTPUT_SOURCE "${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}_source.cpp")
  set(OUTPUT_HEADER "${CMAKE_CURRENT_BINARY_DIR}/rep_${FILE_NAME}_replica.h")

  # 查找repc工具
  find_program(REPC_EXECUTABLE NAMES repc)

  # 添加自定义命令来生成源代码
  add_custom_command(
    OUTPUT ${OUTPUT_HEADER}
    COMMAND ${REPC_EXECUTABLE} -i rep -o replica ${REP_FILE} ${OUTPUT_HEADER}
    DEPENDS ${REP_FILE}
    COMMENT "Generating Qt Remote Object sources for ${REP_FILE}"
    )
    set_property(GLOBAL APPEND PROPERTY GENERATED_REP_HEADERS ${OUTPUT_HEADER})
endmacro()

macro(qt_generate_rep_source REP_FILE)
  # 确定输出文件名
  get_filename_component(FILE_NAME ${REP_FILE} NAME_WE)
  set(OUTPUT_HEADER "${CMAKE_CURRENT_BINARY_DIR}/rep_${FILE_NAME}_source.h")

  # 查找repc工具
  find_program(REPC_EXECUTABLE NAMES repc)

  # 添加自定义命令来生成源代码
  add_custom_command(
    OUTPUT ${OUTPUT_HEADER}
    COMMAND ${REPC_EXECUTABLE} -i rep -o source ${REP_FILE} ${OUTPUT_HEADER}
    DEPENDS ${REP_FILE}
    COMMENT "Generating Qt Remote Object sources for ${REP_FILE}"
    )
    set_property(GLOBAL APPEND PROPERTY GENERATED_REP_HEADERS ${OUTPUT_HEADER})
endmacro()

function(rep_replica)
    message("========REPLICA ${ARGC}========")
    foreach(arg IN LISTS ARGV)
        message(-------${arg}-------)
        list(APPEND REP_REPLICA ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${arg})
    endforeach()
    # 更新SOURCES变量到父作用域，如果这个宏在一个函数内被调用
    set(REP_REPLICA ${REP_REPLICA} PARENT_SCOPE)
endfunction()

function(rep_source)
    message("========SOURCE ${ARGC}========")
    foreach(arg IN LISTS ARGV)
        list(APPEND REP_SOURCES ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${arg})
    endforeach()
    # 更新SOURCES变量到父作用域，如果这个宏在一个函数内被调用
    set(REP_SOURCES ${REP_SOURCES} PARENT_SCOPE)
endfunction()

function(rep_merged)
    message("========REP_MERGEDS ${ARGC}========")
    foreach(arg IN LISTS ARGV)
        list(APPEND REP_MERGEDS ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${arg})
    endforeach()
    # 更新SOURCES变量到父作用域，如果这个宏在一个函数内被调用
    set(REP_MERGEDS ${REP_MERGEDS} PARENT_SCOPE)
endfunction()

function(rep_file)
    message("========REP_FILES ${ARGC}========")
    foreach(arg IN LISTS ARGV)
        list(APPEND REP_FILES ${ROOT_DIR}/${MODULE}/tests/${TEST_TYPE}/${arg})
    endforeach()
    # 更新SOURCES变量到父作用域，如果这个宏在一个函数内被调用
    set(REP_FILES ${REP_FILES} PARENT_SCOPE)
endfunction()
